<template>
    <div :class="{ 'show': show }" class="header-search">
        <svg-icon class-name="search-icon" icon-class="search" @click.stop="click" />
        <el-select ref="headerSearchSelect" v-model="search" :remote-method="querySearch" class="header-search-select"
            default-first-option filterable placeholder="Search" remote @change="change">
            <el-option v-for="option in options" :key="option.item.path" :label="option.item.title.join(' > ')"
                :value="option.item" />
        </el-select>
    </div>
</template>

<script lang="ts" setup>
// import Fuse from 'fuse.js/dist/fuse.min.js'
import path from 'path-browserify'
import { useRouter } from 'vue-router'
import { usePermissionStoreHook } from "@/store/modules/permission"
const permissionStore = usePermissionStoreHook()
const router = useRouter()
const search = ref("")
let options = reactive<any[]>([])
let searchPool = reactive([])
let show = ref(false)
// const fuse = ref(undefined)
const headerSearchSelect = ref(null)

// 获取页面的实例对象
const { proxy } = getCurrentInstance() as any;

const routes = computed(() => {
    return permissionStore.routes
})

onMounted(() => {
    searchPool = generateRoutes(routes)
})
watch(routes, () => {
    searchPool = generateRoutes(routes)
})
watch(searchPool, (list) => {
    initFuse(list)
})

watch(show, (value) => {
    if (value) {
        document.body.addEventListener('click', close)
    } else {
        document.body.removeEventListener('click', close)
    }
})
const click = () => {
    show.value = !show.value
    if (show.value) {
        //@ts-ignore
        proxy?.$refs.headerSearchSelect && proxy?.$refs.headerSearchSelect.focus()
    }
}

const close = () => {
    //@ts-ignore
    headerSearchSelect && headerSearchSelect.blur()
    options = []
    show.value = false
}

const change = (val) => {
    const path = val.path;
    if (ishttp(val.path)) {
        // http(s):// 路径新窗口打开
        const pindex = path.indexOf("http");
        window.open(path.substr(pindex, path.length), "_blank");
    } else {
        router.push(val.path)
    }
    search.value = ''
    options = []
    nextTick(() => {
        show.value = false
    })
}

const initFuse = (list) => {
    // fuse.value = new Fuse(list, {
    //     shouldSort: true,
    //     threshold: 0.4,
    //     location: 0,
    //     distance: 100,
    //     maxPatternLength: 32,
    //     minMatchCharLength: 1,
    //     keys: [{
    //         name: 'title',
    //         weight: 0.7
    //     }, {
    //         name: 'path',
    //         weight: 0.3
    //     }]
    // })
}

const generateRoutes = (routes, basePath = '/', prefixTitle = []) => {
    let res = []
    const routerList: any = toRaw(routes.value)
    if (routerList) {
        for (const router of routerList) {
            // skip hidden router
            if (router.hidden) {
                continue
            }

            const data = {
                path: !ishttp(router.path) ? path.resolve(basePath, router.path) : router.path,
                title: [...prefixTitle]
            }

            if (router.meta && router.meta.title) {
                //@ts-ignore
                data.title = [...data.title, router.meta.title]

                if (router.redirect !== 'noRedirect') {
                    // only push the routes with title
                    // special case: need to exclude parent router without redirect
                    //@ts-ignore
                    res.push(data)
                }
            }

            // recursive child routes
            if (router.children) {
                const tempRoutes = generateRoutes(router.children, data.path, data.title)
                if (tempRoutes.length >= 1) {
                    res = [...res, ...tempRoutes]
                }
            }
        }
    }
    return res
}

const querySearch = (query) => {
    if (query !== '') {
        // @ts-ignore
        options = fuse.search(query)
    } else {
        options = []
    }
}
const ishttp = (url) => {
    return url.indexOf('http://') !== -1 || url.indexOf('https://') !== -1
}
</script>

<script lang="ts">
// fuse is a lightweight fuzzy-search module
// make search results more in line with expectations


export default {
    name: 'HeaderSearch'
}
</script>

<style lang="scss" scoped>
.header-search {
    font-size: 0 !important;

    .search-icon {
        cursor: pointer;
        font-size: 18px;
        vertical-align: middle;
    }

    .header-search-select {
        font-size: 18px;
        transition: width 0.2s;
        width: 0;
        overflow: hidden;
        background: transparent;
        border-radius: 0;
        display: inline-block;
        vertical-align: middle;

        ::v-deep .el-input__inner {
            border-radius: 0;
            border: 0;
            padding-left: 0;
            padding-right: 0;
            box-shadow: none !important;
            border-bottom: 1px solid #d9d9d9;
            vertical-align: middle;
        }
    }

    &.show {
        .header-search-select {
            width: 210px;
            margin-left: 10px;
        }
    }
}
</style>
